

/*
* chinese checkers
*/

/*
* constants
*/
var sqrt3 = Math.sqrt(3),
	distance = 33,
	radius = 15,
	offsetX = 15,
	offsetY = 65;
function GameSetting(number){
	this.number = number || 2;
	this.sides = this.getGameSides(this.number);
}
GameSetting.prototype = {
	getGameSides: function (number){
		var sides;
		switch(number){
		case 2:
			sides = [3, 6];
			break;
		case 3:
			sides = [1, 3, 5];
			break;
		case 4:
			sides = [1, 2, 4, 5];
			break;
		case 6:
		default:
			sides = [1, 2, 3, 4, 5, 6]
			break;
		}
		return sides;
	},
	isTarget: function (originSide, targetSide){
		return Math.abs(targetSide - originSide) == 3;
	},
	onGame: function(ixColor){
		return this.sides.indexOf(ixColor) >= 0;
	}
}

var defaultStrokeColor = 'black',
	clickStrokeColor = '#999',
	emptyColor = 'white',
	reachableColor = '#AAA';

var colors = [emptyColor, 'red', 'blue', 'green', 'pink', 'yellow', 'orange', reachableColor];
var directions = [
 [1, 0], [-1, 0],
 [0, 1], [0, -1],
 [1, -1], [-1, 1]
];

/* 17 rows
   13 cols
*/

var board = [
   /*1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17*/
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0],/*1*/
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0],/*2*/
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 0, 0, 0, 0, 0],/*3*/
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0],/*4*/
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0],/*5*/
 [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0],/*6*/
 [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0],/*7*/
 [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0],/*8*/
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],/*9*/
 [0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0],/*10*/
 [0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0],/*11*/
 [0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0],/*12*/
 [0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0],/*13*/
 [0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],/*14*/
 [0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],/*15*/
 [0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],/*16*/
 [0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],/*17*/
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

function drawCircles( paper, startX, y, numbers, row, startCol ){
	var x = startX, col = startCol;
	while( numbers-- ){
		var ixColor = board[row][col];
		var color = colors[ixColor];
		var c = paper.circle( x, y, radius );

		c.ixInitialColor = c.ixCurrentColor = ixColor;
		if( game.onGame(ixColor) )
			c.attr({stroke: '#333', fill: color});
		else{
			if( ixColor >= 1 ){
				c.attr({stroke: color});
				c.notProcess = true;
			}
			cntl.setEmpty(c);
		}

		addHandler(c, row, col);
		board[row][col] = c;
		col++;
		x += distance;
	}
}

function addHandler(item, row, col){

	item.reachables = [];
	item.row = row;
	item.col = col;
	item.node.onmouseover = function(event){
		if( cntl.hasSelectedItem() ){
			return false;
		}

		if( cntl.isEmpty(item) || cntl.isReachable(item) ){
			return false;
		}
		item.reachables.length = 0;
		item.reachables = cntl.findReachables(item);
		return false;
	}
	item.node.onclick = function(event){
		if( (item.ixCurrentColor > 0 && !game.onGame(item.ixCurrentColor)) ||
			cntl.isEmpty(item) )
			return false;

		if( cntl.isReachable(item) && cntl.hasSelectedItem() ){
			cntl.move(item);
			cntl.nextTurn();
		}
		else if(!cntl.hasSelectedItem() && cntl.isOnTurn(item) ){
			cntl.setSelected(item);
		}else if(cntl.isSelected(item)){
			cntl.removeSelected();
		}
		return false;
	}
	item.node.onmouseout = function(event){
		if( !game.onGame(item.ixCurrentColor) || cntl.hasSelectedItem() ) return false;
		cntl.removeHover(item);
		cntl.clearReachables(item);
		return false;
	}
}

function Controller(){
	this.turn = 0;
	this.onTurnColor = colors[game.sides[this.turn]];
}
Controller.prototype = {
	selectedItem : null,
	nextTurn: function(){
		this.turn += 1;
		if(this.turn >= game.sides.length){
			this.turn = 0;
		}
		this.onTurnColor = colors[game.sides[this.turn]];
	},
	onTurnColor: null,
	isOnTurn: function(item){
		return item.attr('fill') == this.onTurnColor;
	},
	hasSelectedItem : function(){
		return !!this.selectedItem;
	},
	isSelected : function(item){
		return this.selectedItem === item;
	},
	canMoveTo : function(selectedItem, targetItem){
		if(selectedItem.ixCurrentColor > 0 && selectedItem.ixCurrentColor != targetItem.ixInitialColor)
		console.log('%d-%d', selectedItem.ixCurrentColor, targetItem.ixInitialColor);
		return targetItem.ixInitialColor == 0 ||
			selectedItem.ixCurrentColor == targetItem.ixInitialColor ||
			game.isTarget(selectedItem.ixCurrentColor, targetItem.ixInitialColor);
	},
	isEmpty: function(item){
		return item.attr('fill') == emptyColor;
	},
	isReachable: function(item){
		return item.attr('fill') == reachableColor;
	},
	setReachable: function(item){
		item.attr('fill', reachableColor);
	},
	setEmpty: function(item){
		item.attr('fill', emptyColor);
	},
	setHover: function(item){
	},
	removeHover: function(item){
		item.attr('stroke', defaultStrokeColor);
	},
	setFocus: function(item){
		item.attr('stroke-width', 2);
	},
	removeFocus: function(item){
		item.attr('stroke-width', 1);
	},
	/* 设置某个格式被选中了 */
	setSelected : function(item){
		this.setFocus(item)
		this.selectedItem = item;
	},
	removeSelected : function (){
		this.removeFocus(this.selectedItem)
		this.selectedItem = null;
	},
	setSelectedItem : function(row, col){
		var item = board[row][col];
		if( this.isItem(item) ){
			
		}
	},
	move : function (item){
		this.clearReachables(this.selectedItem);
		item.attr({
			'fill': this.selectedItem.attr('fill'),
			'stroke-width': 1,
			'stroke': defaultStrokeColor
		});
		this.selectedItem.attr({
			'fill': emptyColor,
			'stroke-width': 1,
			'stroke': defaultStrokeColor
		});
		/* swap ixCurrentColor */
		ixSelectedItemColor = this.selectedItem.ixCurrentColor;
		this.selectedItem.ixCurrentColor = item.ixCurrentColor;
		item.ixCurrentColor = ixSelectedItemColor;

		this.selectedItem = null;
	},
	findReachables : function (item){
		var reachables = []
		var i, r, c, k;
		var row = item.row, col = item.col;
		console.log('origin: row: %d, col: %d', row, col);
		var color = item.attr('fill');
		var ixColor = item.ixCurrentColor;
		for(k in directions){
			d = directions[k];
			r = row + d[0];
			c = col + d[1];
			i = board[r][c];
			if(!i) continue;
			if( cntl.isEmpty(i) ){
				if( cntl.canMoveTo(item, i) ){
					cntl.setReachable(i);
					reachables.push(i);
				}
			}
		}
		var checked = {}
		search(item, row, col, color, reachables);
		function search(item, row, col, color, reachables){
			var i, r, c, k;
			console.log('row: %d, col: %d', row, col);
			checked[row + ':' + col] = true;
			for(k in directions){
				d = directions[k];
				r = row + d[0];
				c = col + d[1];
				i = board[r][c];
				if(!i) continue;
				if(checked[r + ':' + c]){
					continue;
				}
				/*遇到棋子，跳过去*/
				if(!cntl.isEmpty(i) && !cntl.isReachable(i) ){
					r = r + d[0];
					c = c + d[1];
					i = board[r][c];
					/*如果这里是个空位，那就检查是否可以继续跳*/
					if( i && cntl.isEmpty(i) ){
						if( cntl.canMoveTo(item, i) ){
							cntl.setReachable(i);
							reachables.push(i);
						}
						search(i, r, c, color, reachables);
					}
				}
			}
		}
		return reachables;
	},
	clearReachables : function(item){
		for(var i in item.reachables){
			item.reachables[i].attr('fill', emptyColor);
		}
		item.reachables.length = 0;
	},
}

function drawBoard(paper){
	var i, row = 1, col = 13;
	var x = offsetX + distance * 6,
		y = offsetY;
	for( i = 1; i <= 4; i++ ){
		drawCircles( paper, x, y, i, row++, col-- );
		x -= distance / 2;
		y += distance * sqrt3 / 2;
	}
	x = offsetX;
	col = 5
	for( i = 13; i >= 9; i-- ){
		drawCircles( paper, x, y, i, row++, col );
		x += distance / 2;
		y += distance * sqrt3 / 2;
	}
	x -= distance;
	col = 4;
	for( i = 10; i <= 13; i++ ){
		drawCircles( paper, x, y, i, row++, col-- );
		x -= distance / 2;
		y += distance * sqrt3 / 2;
	}
	var x = offsetX + distance * 4.5;
	col = 5;
	for( i = 4; i >= 1; i-- ){
		drawCircles( paper, x, y, i, row++, col );
		x += distance / 2;
		y += distance * sqrt3 / 2;
	}
}

var gameNumbers = 3;
var game = new GameSetting(gameNumbers);
var cntl = new Controller();

window.onload = function(){
var width = distance * 13 * 2
var r = Raphael('cc', width, 1000);

drawBoard(r);

r.circle( 10, 10, radius ).attr({stroke: '#333', fill: 'blue'});

//r.show();

}

